HammerDB で RDBMS のベンチマークを取ってみる(PostgreSQL編)
ウィスキー、シガー、パイプをこよなく愛する大栗です。
最近 RDBMS のパフォーマンスを計測する機会があったので、手順をまとめておこうと思います。以前のエントリなどではJdbcRunnerを使用することが多かったのですが、今回は別のツールである HammerDB を使用しました。このエントリーでは PostgreSQL を対象としたベンチマークを実施します。
MySQL 版も書きました。MySQL での手順を確認したい方は、以下のエントリを御覧ください。
HammerDB
HammerDB は[Steve Shaw]氏を中心として開発を行っており、トランザクション処理性能評議会(TPC)がサポートしているオープンソースのデータベースベンチマークアプリケーションです。HammerDB では世界的に利用者が多い以下のデータベースをサポートしています。
- Oracle (TimesTen)
- SQL Server
- Db2
- MySQL (Amazon Aurora)
- PostgreSQL (ExterpriseDB / Amazon Redshift / Greenplum)
- MariaDB
サポートしているベンチマーク指標は以下のものになります。将来的に TPC-E をサポートする計画もあるようです。
- TPROC-C
- TPC-C の派生ベンチマーク
- オンライントランザクション処理 (OLTP) のベンチマークで卸売業者の業務モデルを模しています
- 詳細はドキュメントを参照
- TPROC-H
- TPC-H の派生ベンチマーク
- 意思決定支援ベンチマークで、大量のデータを調査し、複雑なクエリを実行します
- 詳細はドキュメントを参照
やってみる
注意
ベンチマーク結果は、データベース・ソフトウェアや提供環境により実施や公開が制限されている場合があります。例えば Oracle ではベンチマークテストの結果は公開を禁じられています。AWS では AWS Service Terms の 1.8 に準じる必要があります。
事前準備
ベンチマークの環境は以下としています。
- HammerDB : version 4.3
- クライアント環境
- AMI : ami-08a8688fb7eacb171 (amzn2-ami-kernel-5.10-hvm-2.0.20220207.1-x86_64-gp2)
- OS : Amazon Linux 2
- psql (PostgreSQL) 13.3
- データベース環境
- PostgreSQL 13
また、クライアントからデータベースへのネットワーク接続が問題なく出来ることとします。
Extras Library の PostgreSQL 13 を有効化します。
$ sudo amazon-linux-extras enable postgresql13
postgresql
とpostgresql-devel
をインストールします。
$ sudo yum clean metadata && sudo yum install -y postgresql postgresql-devel
HammerDB をダウンロードします。
$ wget https://github.com/TPC-Council/HammerDB/releases/download/v4.3/HammerDB-4.3-Linux.tar.gz
ダウンロードしたファイルを解凍します。
$ tar xvfz HammerDB-4.3-Linux.tar.gz
解凍したディレクトリへ移動します。
$ cd HammerDB-4.3
HammerDB の CLI を起動します。
$ ./hammerdbcli
librarycheck
コマンドでライブラリのインストール状況をチェックします。出力される結果の中で、PostgreSQL の内容がSuccess
になっていることを確認します。
hammerdb>librarycheck Checking database library for Oracle ・ ・ ・ Checking database library for PostgreSQL Success ... loaded library Pgtcl for PostgreSQL ・ ・ ・
一旦 HammerDB CLI を終了します。
hammerdb>exit
TPROC-C の実施
TPC-C の派生ベンチマークである TPROC-C を実行してみます
HammerDB の CLI を起動します。
$ ./hammerdbcli
対象データベースを PostgreSQL に設定し、ベンチマークを TPROC-C に設定します。
hammerdb>dbset db pg hammerdb>dbset bm TPROC-C
設定内容を確認します。この内容について必要な項目を設定していきます。
hammerdb>print dict Dictionary Settings for PostgreSQL connection { pg_host = localhost pg_port = 5432 pg_sslmode = prefer } tpcc { pg_count_ware = 1 pg_num_vu = 1 pg_superuser = postgres pg_superuserpass = postgres pg_defaultdbase = postgres pg_user = tpcc pg_pass = tpcc pg_dbase = tpcc pg_tspace = pg_default pg_vacuum = false pg_dritasnap = false pg_oracompat = false pg_storedprocs = false pg_partition = false pg_total_iterations = 10000000 pg_raiseerror = false pg_keyandthink = false pg_driver = test pg_rampup = 2 pg_duration = 5 pg_allwarehouse = false pg_timeprofile = false pg_async_scale = false pg_async_client = 10 pg_async_verbose = false pg_async_delay = 1000 pg_connect_pool = false }
接続先のホスト名と接続ポートを設定します。
hammerdb>diset connection pg_host xxxxxxxxxxxx.example.com hammerdb>diset connection pg_port 99999
管理者ユーザ名、管理者パスワード、初期接続先のデータベースを入力します。
hammerdb>diset tpcc pg_superuser XXXXX hammerdb>diset tpcc pg_superuserpass XXXXXXXXXXXXXXXX hammerdb>diset tpcc pg_defaultdbase sampledb
必要に応じて、ベンチマークを実行する際のユーザ名、パスワード、データベースを入力します。ここで設定するユーザとデータベースは存在しない場合管理者ユーザを使用して自動で作成されます。
hammerdb>diset tpcc pg_user tpcc hammerdb>diset tpcc pg_pass tpcc hammerdb>diset tpcc pg_dbase tpcc
warehouse を指定します。倉庫を表し、データベース全体のサイズを決める因子になっています。
hammerdb>diset tpcc pg_count_ware 100
データロード時の同時実行数を指定します。
hammerdb>diset tpcc pg_num_vu 4
設定した内容を確認します。
hammerdb>print dict Dictionary Settings for PostgreSQL connection { pg_host = xxxxxxxxxxxx.example.com pg_port = 99999 pg_sslmode = prefer } tpcc { pg_count_ware = 100 pg_num_vu = 4 pg_superuser = XXXXX pg_superuserpass = XXXXXXXXXXXXXXXX pg_defaultdbase = sampledb pg_user = tpcc pg_pass = tpcc pg_dbase = tpcc pg_tspace = pg_default pg_vacuum = false pg_dritasnap = false pg_oracompat = false pg_storedprocs = false pg_partition = false pg_total_iterations = 10000000 pg_raiseerror = false pg_keyandthink = false pg_driver = test pg_rampup = 2 pg_duration = 5 pg_allwarehouse = false pg_timeprofile = false pg_async_scale = false pg_async_client = 10 pg_async_verbose = false pg_async_delay = 1000 pg_connect_pool = false }
ベンチマーク用のスキーマとデータを作成します。
hammerdb>buildschema
データの作成が完了すると、以下のようなメッセージが表示されます。一度改行するとhammerdb>
のプロンプトに戻ります。
Vuser 1:TPCC SCHEMA COMPLETE Vuser 1:FINISHED SUCCESS ALL VIRTUAL USERS COMPLETE
データを作成したときの仮想ユーザを削除します。
hammerdb>vudestroy
次にベンチマークの実施設定を行います。ベンチマークの実施時はドライバスクリプトの設定をtimed
にします。
hammerdb>diset tpcc pg_driver timed
クライアント側のタイムプロファイルを有効にします。
hammerdb>diset tpcc pg_timeprofile true
dbset と diset で設定した内容をロードします
hammerdb>loadscript
仮想ユーザの構成を確認します。
hammerdb>print vuconf Virtual Users = 5 User Delay(ms) = 500 Repeat Delay(ms) = 500 Iterations = 1 Show Output = 1 Log Output = 0 Unique Log Name = 0 No Log Buffer = 0 Log Timestamps = 0
設定項目を確認します。
hammerdb>vuset Usage: vuset [vu|delay|repeat|iterations|showoutput|logtotemp|unique|nobuff|timestamps] value
ベンチマークを実行する同時実行ユーザー数を定義します。ここでは 8 にしています。
hammerdb>vuset vu 8
ログを出力する設定を行います。
hammerdb>vuset logtotemp 1
ログ名の設定
hammerdb>vuset unique 1
ログへのタイムスタンプ設定を行います。
hammerdb>vuset timestamps 1
実施した設定を確認します。
hammerdb>print vuconf Virtual Users = 8 User Delay(ms) = 500 Repeat Delay(ms) = 500 Iterations = 1 Show Output = 1 Log Output = 1 Unique Log Name = 1 No Log Buffer = 0 Log Timestamps = 1
ベンチマークの実行ユーザを作成します。出力されるログのパスも表示されます。
hammerdb>vucreate Vuser 1 created MONITOR - WAIT IDLE Vuser 2 created - WAIT IDLE Vuser 3 created - WAIT IDLE Vuser 4 created - WAIT IDLE Vuser 5 created - WAIT IDLE Vuser 6 created - WAIT IDLE Vuser 7 created - WAIT IDLE Vuser 8 created - WAIT IDLE Vuser 9 created - WAIT IDLE Logging activated to /tmp/hammerdb_1234ABCD5678EFGH1234ABCD.log 9 Virtual Users Created with Monitor VU
実行ユーザのステータスを確認します。各ユーザのステータスがWAIT IDLE
になっていることを確認します。
hammerdb>vustatus 1 = WAIT IDLE 2 = WAIT IDLE 3 = WAIT IDLE 4 = WAIT IDLE 5 = WAIT IDLE 6 = WAIT IDLE 7 = WAIT IDLE 8 = WAIT IDLE 9 = WAIT IDLE
ベンチマークを実行します。
hammerdb>vurun Vuser 1:RUNNING Vuser 1:Initializing xtprof time profiler Vuser 1:Beginning rampup time of 2 minutes ・ ・ ・
ALL VIRTUAL USERS COMPLETE
が表示されるとベンチマークの完了です。TEST RESULT
の行に結果が出力されます。また時間情報が出力されたログのパスも出力されています。
結果にはNOPM
とTPM
があります。NOPM は New Orders per Minute の略で、新規発注処理を1分間に何回できたかを表しています。TPC-C の場合は分間の新規発注処理数を tpmC で表しますが、HammerDB では 厳密には TPC-C に準拠していないため使用できません。そのため NOPM という指標を使用しています。TPM は Transactions per Minute の略で、オンライン トランザクション カウンターに表示される値で異なるデータベース間では比較できません。
Vuser 1:Test complete, Taking end Transaction Count. Vuser 1:8 Active Virtual Users configured Vuser 1:TEST RESULT : System achieved 99999 NOPM from 99999 PostgreSQL TPM Vuser 1:Gathering timing data from Active Virtual Users... Vuser 4:FINISHED SUCCESS Vuser 5:FINISHED SUCCESS Vuser 2:FINISHED SUCCESS Vuser 9:FINISHED SUCCESS Vuser 3:FINISHED SUCCESS Vuser 7:FINISHED SUCCESS Vuser 6:FINISHED SUCCESS Vuser 8:FINISHED SUCCESS Vuser 1:Calculating timings... Vuser 1:Writing timing data to /tmp/hdbxtprofile.log Vuser 1:FINISHED SUCCESS ALL VIRTUAL USERS COMPLETE
ログの中身を確認します。各実行ユーザの結果詳細が出力されており、一番最後に各オペレーションの全体結果が出力されます。
$ cat /tmp/hdbxtprofile.log PostgreSQL Hammerdb Time Profile Report @ Wed Feb 09 09:51:40 UTC 2022 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ >>>>> VIRTUAL USER 2 : ELAPSED TIME : 999999ms >>>>> PROC: NEWORD ・ ・ ・ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ >>>>> SUMMARY OF 8 ACTIVE VIRTUAL USERS : MEDIAN ELAPSED TIME : 999999ms >>>>> PROC: NEWORD CALLS: 999999 MIN: 9.999ms AVG: 9.999ms MAX: 999.999ms TOTAL: 9999999.999ms P99: 99.999ms P95: 9.999ms P50: 9.999ms SD: 9999.999 RATIO: 99.999% >>>>> PROC: PAYMENT CALLS: 999999 MIN: 9.999ms AVG: 9.999ms MAX: 999.999ms TOTAL: 9999999.999ms P99: 99.999ms P95: 9.999ms P50: 9.999ms SD: 9999.999 RATIO: 99.999% >>>>> PROC: DELIVERY CALLS: 999999 MIN: 9.999ms AVG: 9.999ms MAX: 999.999ms TOTAL: 9999999.999ms P99: 99.999ms P95: 9.999ms P50: 9.999ms SD: 9999.999 RATIO: 99.999% >>>>> PROC: SLEV CALLS: 999999 MIN: 9.999ms AVG: 9.999ms MAX: 999.999ms TOTAL: 9999999.999ms P99: 99.999ms P95: 9.999ms P50: 9.999ms SD: 9999.999 RATIO: 99.999% >>>>> PROC: OSTAT CALLS: 999999 MIN: 9.999ms AVG: 9.999ms MAX: 999.999ms TOTAL: 9999999.999ms P99: 99.999ms P95: 9.999ms P50: 9.999ms SD: 9999.999 RATIO: 99.999% +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
TPROC-H の実施
TPC-H の派生ベンチマークである TPROC-H を実行してみます
HammerDB の CLI を起動します。
$ ./hammerdbcli
対象データベースを PostgreSQL に設定し、ベンチマークを TPROC-H に設定します。
hammerdb>dbset db pg hammerdb>dbset bm TPROC-H
設定内容を確認します。この内容について必要な項目を設定していきます。
hammerdb>print dict Dictionary Settings for PostgreSQL connection { pg_host = localhost pg_port = 5432 pg_sslmode = prefer } tpch { pg_scale_fact = 1 pg_tpch_superuser = postgres pg_tpch_superuserpass = postgres pg_tpch_defaultdbase = postgres pg_tpch_user = tpch pg_tpch_pass = tpch pg_tpch_dbase = tpch pg_tpch_tspace = pg_default pg_tpch_gpcompat = false pg_tpch_gpcompress = false pg_num_tpch_threads = 1 pg_total_querysets = 1 pg_raise_query_error = false pg_verbose = false pg_refresh_on = false pg_degree_of_parallel = 2 pg_update_sets = 1 pg_trickle_refresh = 1000 pg_refresh_verbose = false pg_cloud_query = false pg_rs_compat = false }
接続先のホスト名と接続ポートを設定します。
hammerdb>diset connection pg_host xxxxxxxxxxxx.example.com hammerdb>diset connection pg_port 99999
管理者ユーザ名、管理者パスワード、初期接続先のデータベースを入力します。
hammerdb>diset tpch pg_tpch_superuser XXXXX hammerdb>diset tpch pg_tpch_superuserpass XXXXXXXXXXXXXXXX hammerdb>diset tpch pg_tpch_defaultdbase sampledb
必要に応じて、ベンチマークを実行する際のユーザ名、パスワード、データベースを入力します。ここで設定するユーザとデータベースは存在しない場合管理者ユーザを使用して自動で作成されます。
hammerdb>diset tpch pg_tpch_user tpch hammerdb>diset tpch pg_tpch_pass tpch hammerdb>diset tpch pg_tpch_dbase tpch
pg_scale_fact を指定します。データのサイズです。以下の値のいずれかを入力します。
1, 10, 30, 100, 300, 1000, 3000, 10000, 30000, 100000
hammerdb>diset tpch pg_scale_fact 100
データロード時の同時実行数を指定します。
hammerdb>diset tpch pg_num_tpch_threads 4
設定した内容を確認します。
hammerdb>print dict Dictionary Settings for PostgreSQL connection { pg_host = xxxxxxxxxxxx.example.com pg_port = 99999 pg_sslmode = prefer } tpch { pg_scale_fact = 100 pg_tpch_superuser = XXXXX pg_tpch_superuserpass = XXXXXXXXXXXXXXXX pg_tpch_defaultdbase = sampledb pg_tpch_user = tpch pg_tpch_pass = tpch pg_tpch_dbase = tpch pg_tpch_tspace = pg_default pg_tpch_gpcompat = false pg_tpch_gpcompress = false pg_num_tpch_threads = 1 pg_total_querysets = 1 pg_raise_query_error = false pg_verbose = false pg_refresh_on = false pg_degree_of_parallel = 2 pg_update_sets = 1 pg_trickle_refresh = 1000 pg_refresh_verbose = false pg_cloud_query = false pg_rs_compat = false }
ベンチマーク用のスキーマとデータを作成します。
hammerdb>buildschema
データの作成が完了すると、以下のようなメッセージが表示されます。一度改行するとhammerdb>
のプロンプトに戻ります。
Vuser 1:TPCH SCHEMA COMPLETE Vuser 1:FINISHED SUCCESS ALL VIRTUAL USERS COMPLETE TPROC-H Driver Script
データを作成したときの仮想ユーザを削除します。
hammerdb>vudestroy
dbset と diset で設定した内容をロードします
hammerdb>loadscript
仮想ユーザの構成を確認します。
hammerdb>print vuconf Virtual Users = 5 User Delay(ms) = 500 Repeat Delay(ms) = 500 Iterations = 1 Show Output = 1 Log Output = 0 Unique Log Name = 0 No Log Buffer = 0 Log Timestamps = 0
ベンチマークを実行する同時実行ユーザー数を定義します。ここでは 1 にしています。
hammerdb>vuset vu 1
ログを出力する設定を行います。
hammerdb>vuset logtotemp 1
ログ名の設定
hammerdb>vuset unique 1
実施した設定を確認します。
hammerdb>print vuconf Virtual Users = 1 User Delay(ms) = 500 Repeat Delay(ms) = 500 Iterations = 1 Show Output = 1 Log Output = 1 Unique Log Name = 1 No Log Buffer = 0 Log Timestamps = 0
ベンチマークの実行ユーザを作成します。出力されるログのパスも表示されます。
hammerdb>vucreate Vuser 1 created - WAIT IDLE Logging activated to /tmp/hammerdb_ABCD1234EFGH5678IJKM1234.log 1 Virtual Users Created
実行ユーザのステータスを確認します。各ユーザのステータスがWAIT IDLE
になっていることを確認します。
hammerdb>vustatus 1 = WAIT IDLE
ベンチマークを実行します。
hammerdb>vurun Vuser 1:RUNNING Vuser 1:Executing Query 14 (1 of 22) ・ ・ ・ Vuser 1:Completed 1 query set(s) in 99 seconds Vuser 1:Geometric mean of query times returning rows (22) is 9.99999 Vuser 1:FINISHED SUCCESS ALL VIRTUAL USERS COMPLETE TPROC-H Driver Script
ログの中身を確認します。各クエリの実行時間が出力されています。TPC-H では QphH@Size という 1時間当たりの複合クエリのパフォーマンスを指標にしたものを使用しますが、HammerDB では派生の TPROC-H を使用しているため使用できません。結果を評価するにはクエリの実行時間を個別に比較するなどが良いかもしれません。
$ cat /tmp/hammerdb_ABCD1234EFGH5678IJKM1234.log Hammerdb Log @ Wed Feb 09 14:08:34 UTC 2022 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+- Vuser 1:Executing Query 14 (1 of 22) Vuser 1:query 14 completed in 0.999 seconds Vuser 1:Executing Query 2 (2 of 22) Vuser 1:query 2 completed in 0.999 seconds Vuser 1:Executing Query 9 (3 of 22) Vuser 1:query 9 completed in 0.999 seconds Vuser 1:Executing Query 20 (4 of 22) Vuser 1:query 20 completed in 0.999 seconds Vuser 1:Executing Query 6 (5 of 22) Vuser 1:query 6 completed in 0.999 seconds Vuser 1:Executing Query 17 (6 of 22) Vuser 1:query 17 completed in 0.999 seconds Vuser 1:Executing Query 18 (7 of 22) Vuser 1:query 18 completed in 0.999 seconds Vuser 1:Executing Query 8 (8 of 22) Vuser 1:query 8 completed in 0.999 seconds Vuser 1:Executing Query 21 (9 of 22) Vuser 1:query 21 completed in 0.999 seconds Vuser 1:Executing Query 13 (10 of 22) Vuser 1:query 13 completed in 0.999 seconds Vuser 1:Executing Query 3 (11 of 22) Vuser 1:query 3 completed in 0.999 seconds Vuser 1:Executing Query 22 (12 of 22) Vuser 1:query 22 completed in 0.999 seconds Vuser 1:Executing Query 16 (13 of 22) Vuser 1:query 16 completed in 0.999 seconds Vuser 1:Executing Query 4 (14 of 22) Vuser 1:query 4 completed in 0.999 seconds Vuser 1:Executing Query 11 (15 of 22) Vuser 1:query 11 completed in 0.999 seconds Vuser 1:Executing Query 15 (16 of 22) Vuser 1:query 15 completed in 0.999 seconds Vuser 1:Executing Query 1 (17 of 22) Vuser 1:query 1 completed in 0.999 seconds Vuser 1:Executing Query 10 (18 of 22) Vuser 1:query 10 completed in 0.999 seconds Vuser 1:Executing Query 19 (19 of 22) Vuser 1:query 19 completed in 0.999 seconds Vuser 1:Executing Query 5 (20 of 22) Vuser 1:query 5 completed in 0.999 seconds Vuser 1:Executing Query 7 (21 of 22) Vuser 1:query 7 completed in 0.999 seconds Vuser 1:Executing Query 12 (22 of 22) Vuser 1:query 12 completed in 0.999 seconds Vuser 1:Completed 1 query set(s) in 99 seconds Vuser 1:Geometric mean of query times returning rows (22) is 0.99999
さいごに
HammerDB は、OLTP と OLAP の両方のベンチマークを簡単に行えるツールです。使用するデータベースのパフォーマンスは実ワークロードで確認するのが最適なのですが、なかなか実施するのは難しいです。そのため HammerDB のようなベンチマークテストツールを使用して必要なパフォーマンスを発揮するかの目安を確認すると良いのではないでしょうか。